package com.sise.netty.reactor模型.单线程模型.demo;


import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

@Slf4j
public class NIOServer implements Runnable {


    public int port;

    private ServerSocketChannel serverSocketChannel;

    private Selector selector;

    public NIOServer(int port) throws IOException {
        this.port = port;
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        //设置为非堵塞模式
        serverSocketChannel.configureBlocking(false);
        //让channel注册到选择器上边，并且监听相应的选择器事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }


    public static void main(String[] args) throws IOException {


    }

    @Override
    public void run() {
        try {
            log.debug("开始运行");
            while (selector.select() > 0) {
                Set<SelectionKey> keys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = keys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    if (key.isAcceptable()) {

                        ServerSocketChannel acceptServerSocketChannel = (ServerSocketChannel) key.channel();
                        SocketChannel socketChannel = acceptServerSocketChannel.accept();
                        socketChannel.configureBlocking(false);

                        System.out.println("以获取请求连接：" + socketChannel.getRemoteAddress());
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    } else if (key.isReadable()) {

                        SocketChannel socketChannel = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        int count = socketChannel.read(buffer);

                        if (count <= 0) {
                            socketChannel.close();
                            key.cancel();
                            System.out.println("连接关闭");
                            continue;
                        }
                    }
                    keys.remove(key);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}